package com.example.voucher.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;

import com.example.voucher.common.TenantCodeThreadLocal;
import com.example.voucher.config.SubjectConfigRegister;
import com.example.voucher.config.bo.SubjectMappingConfigBO;
import com.example.voucher.config.bo.SubjectReducingConfigBO;
import com.example.voucher.contract.VoucherItemAccessor;
import com.example.voucher.contract.VoucherItemCapable;
import com.example.voucher.contract.spi.DefaultVoucherItemAccessor;
import com.example.voucher.entity.Voucher;
import com.example.voucher.extension.ExtensionImpl;
import com.example.voucher.service.AbstractVoucherItemConvertService;
import com.example.voucher.service.VoucherItemConvertService;
import com.google.common.collect.Lists;

@ExtensionImpl(extendFrom = VoucherItemConvertService.class)
public class DefaultVoucherItemConvertService extends AbstractVoucherItemConvertService
    implements VoucherItemConvertService {

    @Autowired
    private SubjectConfigRegister subjectConfig;

    @Override
    public List<Voucher> convert(List<VoucherItemCapable> srcList) {
        List<Voucher> retList = Lists.newArrayList();
        
        // List<VoucherItemCapable> ---> List<VoucherItemAccessor>
        // 只读的list转化为可读写的list，方便后续的分组和汇总
        List<VoucherItemAccessor> accessorList =
            srcList.stream().map(t -> new DefaultVoucherItemAccessor(t)).collect(Collectors.toList());
        srcList.clear();
        srcList = null;
        
        String tenantCode = TenantCodeThreadLocal.getTenantCode();
        // 先按照场景分组，比如某租户，进项货款有3个科目，进项费用有3个科目，支持同时勾选货款和费用发票生成凭证的情况
        Map<String, List<VoucherItemAccessor>> scenarioMap =
            accessorList.stream().collect(Collectors.groupingBy(VoucherItemAccessor::getScenario));
        for (Entry<String, List<VoucherItemAccessor>> entry : scenarioMap.entrySet()) {
            String scenarioCode = entry.getKey();
            // 来源数据
            List<VoucherItemAccessor> fromList = entry.getValue();
            // 每一条明细生成几个凭证科目 List<SubjectCode>
            List<String> subjectList = subjectConfig.getSubjectConfig(tenantCode, scenarioCode);
            // 凭证科目分组汇总相关的配置 K=SubjectCode
            Map<String, SubjectReducingConfigBO> reducingMap = subjectConfig.getReducingConfig(tenantCode, scenarioCode);
            // 凭证科目映射金蝶凭证表相关的配置 K=SubjectCode            
            Map<String, SubjectMappingConfigBO> mappingMap = subjectConfig.getMappingConfig(tenantCode, scenarioCode);
            retList.addAll(convertWithConfig(fromList, subjectList, reducingMap, mappingMap));
        }
        return retList;
    }

}
